package bootstrap

import (
	"context"
	"go-mp-starter/app/middleware"
	"go-mp-starter/global"
	"go-mp-starter/routers"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/gin-gonic/gin"
)

func setupRouter() *gin.Engine {
	// 设置生产模式
	if global.App.Config.App.Env == "production" {
		gin.SetMode(gin.ReleaseMode)
	}

	router := gin.New()
	// 设置错误日志记录中间件
	router.Use(gin.Logger(), middleware.CustomRecovery())
	// 跨域中间件
	router.Use(middleware.Cors())

	// 静态资源
	router.StaticFile("/", "./static/dist/index.html")
	router.Static("/assets", "./static/dist/assets")
	router.StaticFile("/favicon.ico", "./static/dist/favicon.ico")
	// 其他静态资源
	router.Static("/public", "./static")
	router.Static("/storage", "./storage/app/public")

	// 注册API路由分组
	apiGroup := router.Group("/api")
	routers.SetApiGroupRoutes(apiGroup)

	return router
}

// 启动http服务器
func RunServer() {
	// 获取gin.Engine
	router := setupRouter()
	// 设置http.Server
	svr := &http.Server{
		Addr:    ":" + global.App.Config.App.Port,
		Handler: router,
	}
	// 以协程启动
	go func() {
		if err := svr.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("ListenAndServe: %s\n", err)
		}
	}()

	// 等待中断信号优雅关闭服务器(设置5秒超时)
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	// 阻塞等待关闭信号
	<-quit
	log.Println("Shutdown Server...")

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	// 超时前返回释放上下文资源
	defer cancel()
	// 关闭服务
	if err := svr.Shutdown(ctx); err != nil {
		log.Fatalf("Server Shutdown: %s\n", err)
	}
	log.Println("Server Exiting")
}
